package com.artup.interceptor;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSONObject;
import com.artup.common.Constants;
import com.artup.common.ResponseResult;
import com.artup.pojo.User;

/**
 * 登陆拦截器
 * @author hapday
 * @date 2017年8月31日 @Time 下午7:48:20
 */
public class SigninInterceptor extends HandlerInterceptorAdapter{
	private final Logger LOGGER = LoggerFactory.getLogger(SigninInterceptor.class);
	
//	private final String webHost = PropertiesUtils.getValue("artup.pms.url.perfix");

//	@Autowired
//	private AuthorityWebService authorityWebService;
	
	/*
	 * 利用正则映射到需要拦截的路径    
	 
    private String mappingURL;
    
    public void setMappingURL(String mappingURL) {    
               this.mappingURL = mappingURL;    
    }   
  */
    /** 
     * 在业务处理器处理请求之前被调用 
     * 如果返回false 
     *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
     * 如果返回true 
     *    执行下一个拦截器,直到所有的拦截器都执行完毕 
     *    再执行被拦截的Controller 
     *    然后进入拦截器链, 
     *    从最后一个拦截器往回执行所有的postHandle() 
     *    接着再从最后一个拦截器往回执行所有的afterCompletion() 
     */  
    @Override  
    public boolean preHandle(HttpServletRequest request,  
            HttpServletResponse response, Object handler) throws Exception {  
    	HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//		System.err.println("--------------------------");
//		System.err.println("-------------拦截器-------------");
//		System.err.println("--------------------------");
		
    	httpServletResponse.addHeader("Access-Control-Allow-Origin", "*");		// 允许 JS 跨域
		httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");		// 允许 JS 跨域
		
		String requestURI = httpServletRequest.getRequestURI();
//		String contextPath = httpServletRequest.getContextPath();

		String [] excludeUrls = this.getExcludeURLs();
		
		if(0 < excludeUrls.length){
			for(String excludeUrl : excludeUrls){
				if(requestURI.contains(excludeUrl)){
					return true;
				}
			}
		}
		
		HttpSession httpSession = httpServletRequest.getSession();
		
		if(null == httpSession) {
			LOGGER.debug("会话已过期！");
			
			this.printToClient(httpServletResponse, "已退出");

			/*if(isAjaxRequest(httpServletRequest)) {
				this.printToClient(httpServletResponse, "已退出");
			} else {
				this.authorityWebService.signout(httpSession, null);
				
				httpServletResponse.sendRedirect(webHost + "signin.html");
			}*/
			
			return false;
		}
		
		LOGGER.debug("httpSessionId = {}", httpSession.getId());
		
		User user = (User) httpSession.getAttribute("user");
		
		if(null == user) {
			LOGGER.debug("已退出！");
			
			this.printToClient(httpServletResponse, "已退出");
			
			/*if(isAjaxRequest(httpServletRequest)) {
				this.printToClient(httpServletResponse, "已退出");
			} else {
				this.authorityWebService.signout(httpSession, null);
				
				httpServletResponse.sendRedirect(webHost + "signin.html");
			}*/
			
			return false;
		} else {
			return true;
		}
    }  
  
    /**
     * 在业务处理器处理请求执行完成后,生成视图之前执行的动作   
     * 可在modelAndView中加入数据，比如当前时间
     */
    @Override  
    public void postHandle(HttpServletRequest request,  
            HttpServletResponse response, Object handler,  
            ModelAndView modelAndView) throws Exception {   
//    	logger.info("==============执行顺序: 2、postHandle================");  
//        if(modelAndView != null){  //加入当前时间  
//            modelAndView.addObject("var", "测试postHandle");  
//        }  
    }  
  
    /** 
     * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等  
     *  
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion() 
     */  
    @Override  
    public void afterCompletion(HttpServletRequest request,  
            HttpServletResponse response, Object handler, Exception ex)  
            throws Exception {  
//    	logger.info("==============执行顺序: 3、afterCompletion================");  
    }  

    /**
	 * 不被处理的 URL
	 * @return
	 */
	private String [] getExcludeURLs(){
		String [] excludeUrl = new String[]{
//				"global/login",
				"toLogin",
				"login",
				"logout",
				"register",
				"error",
				"*.js",
				".js",
				"admin/blog/queryBlogs"
		}; 
		
		return excludeUrl;
	}
	
	/**
	 * 打印消息到客户端
	 * @param response
	 * @param message
	 * @throws IOException
	 */
	private void printToClient(HttpServletResponse httpServletResponse, String message) throws IOException {
		PrintWriter out = httpServletResponse.getWriter();
		
		ResponseResult responseResult = new ResponseResult();
		responseResult.setStatus(Constants.ACTION_STATUS_LOGOUTED);
		responseResult.setMessage(message);
		
		out.print(JSONObject.toJSON(responseResult));
		out.flush();
		out.close();
	}

	/**
	 * 是否为 AJAX 请求
	 * @param request
	 * @return
	 */
	protected boolean isAjaxRequest(HttpServletRequest request) {
		String requestType = request.getHeader("X-Requested-With");
		
        if("XMLHttpRequest".equals(requestType)) {
            return true;
        } else {
            return false;
        }
	}
}  

